<template>
  <div v-loading="loading" class="crud-content">
    <table-form v-model="table" :addon="addon" :field-items="fieldItems">
      <el-button type="primary" :icon="'MagicStick'" @click="showAiDialog = true">AI设计</el-button>
      <el-button v-if="row.id" type="primary" @click="save()">保存设计（ctrl+s）</el-button>
      <el-button v-else type="success" @click="save()">添加设计</el-button>
      <el-button type="warning" @click="generate()">获取CRUD代码</el-button>
      <el-button type="danger" @click="dialogCrudVisible = true">切换数据表</el-button>
    </table-form>
    <div class="resizable-layout crud-body">
      <!-- 左侧面板 -->
      <div v-show="!layoutConfig.leftCollapsed" class="layout-panel left-panel" :style="{ width: layoutConfig.leftWidth + 'px' }">
        <div class="panel-header">
          <h4>字段组件</h4>
          <div class="panel-controls">
            <el-button type="text" size="small" @click="toggleLeftPanel">
              <el-icon><d-arrow-left /></el-icon>
            </el-button>
          </div>
        </div>
        <div class="panel-content" style="user-select: none">
          <div style="overflow: auto">
            <div v-for="(item, key) in commonFields" :key="key">
              <h4>{{ item.label }}</h4>
              <draggable
                class="dragArea list-group"
                :list="item.fields"
                :group="{ name: 'people', pull: 'clone', put: false }"
                :sort="false"
                :clone="cloneField"
                item-key="index"
              >
                <template #item="{ element }">
                  <el-tag style="margin: 0 10px 10px 0; cursor: move">{{ element.title }}</el-tag>
                </template>
              </draggable>
            </div>
          </div>
        </div>
      </div>

      <!-- 左侧调整手柄 -->
      <div v-show="!layoutConfig.leftCollapsed" class="resize-handle left-handle" @mousedown="startResize('left', $event)"></div>

      <!-- 左侧折叠按钮 -->
      <div v-show="layoutConfig.leftCollapsed" class="collapsed-trigger left-trigger" @click="toggleLeftPanel">
        <el-icon><d-arrow-right /></el-icon>
        <span class="trigger-text">字段组件</span>
      </div>

      <!-- 中间面板 -->
      <div class="layout-panel center-panel">
        <div class="panel-header w-full">
          <div class="flex justify-between items-center w-full">
            <h4>数据表设计</h4>
            <el-button type="info" @click="openHistoryDialog">历史记录</el-button>
          </div>
        </div>
        <div class="field-content panel-content">
          <draggable
            :list="fieldItems"
            group="people"
            class="drag-field w-full bg-#f5f7fa rounded-md p-2 min-h-600px"
            item-key="_id"
            @change="onChange"
          >
            <template #item="{ element, index }">
              <div class="field-item-list" :class="chooseFieldKey === index ? 'choose' : ''" @click="chooseFieldKey = index">
                <el-form :inline="true" class="demo-form-inline">
                  <el-form-item label="字段名">
                    <el-input v-model="element.name" placeholder="输入字段名" style="width: 150px" />
                  </el-form-item>
                  <el-form-item label="字段注释">
                    <el-input v-model="element.comment" placeholder="输入字段注释" style="width: 150px" />
                  </el-form-item>
                </el-form>
                <div class="field-item-button">
                  <el-button type="primary" icon="CopyDocument" circle @click="copyItem(index)" />
                  <el-button type="danger" icon="Delete-Filled" circle @click="deleteItem(index)" />
                </div>
              </div>
            </template>
          </draggable>
          <div v-if="fieldItems.length === 0" class="no-fieldItems">
            <el-empty description="拖拽左侧元素到这里开始设计" />
          </div>
        </div>
      </div>

      <!-- 右侧调整手柄 -->
      <div v-show="!layoutConfig.rightCollapsed" class="resize-handle right-handle" @mousedown="startResize('right', $event)"></div>

      <!-- 右侧面板 -->
      <div v-show="!layoutConfig.rightCollapsed" class="layout-panel right-panel" :style="{ width: layoutConfig.rightWidth + 'px' }">
        <div class="panel-header">
          <h4>字段配置</h4>
          <div class="panel-controls">
            <el-button type="text" size="small" @click="toggleRightPanel">
              <el-icon><d-arrow-right /></el-icon>
            </el-button>
          </div>
        </div>
        <div class="panel-content">
          <crud-form v-if="fieldItems.length > 0" v-model="fieldItems[chooseFieldKey]" :addon="addon" :field-items="fieldItems" />
          <div v-else style="min-height: 500px">
            <el-empty description="从左侧选择一个字段" />
          </div>
        </div>
      </div>

      <!-- 右侧折叠按钮 -->
      <div v-show="layoutConfig.rightCollapsed" class="collapsed-trigger right-trigger" @click="toggleRightPanel">
        <el-icon><d-arrow-left /></el-icon>
        <span class="trigger-text">字段配置</span>
      </div>
    </div>

    <!------------------------------------------ 下面是弹窗部分-------------------------------------------------->

    <!-- 版本对比弹窗 -->
    <el-dialog v-model:visible="dialogVisible" title="版本对比" width="1100px" top="10vh" append-to-body>
      <div style="margin-bottom: 10px">
        {{ fieldItems }}
      </div>
      <div>
        {{ table }}
      </div>
    </el-dialog>
    <el-dialog v-model="dialogCodeVisible" title="在线预览" width="1200px" top="5vh" append-to-body>
      <el-tabs v-model="tabName" v-loading="sloading" tab-position="left">
        <el-tab-pane v-for="(item, key) in codes" :key="key" :label="item.label" :name="key">
          <div style="padding: 10px 0; display: flex; justify-content: space-between; align-items: center">
            <div>
              文件路径：<el-tag>{{ item.path }}</el-tag>
            </div>
            <div>
              <el-button
                type="warning"
                size="small"
                :loading="overwriteLoading"
                :disabled="item.path === '无'"
                @click="overwriteCurrentFile(key, item)"
              >
                覆盖当前文件
              </el-button>
            </div>
          </div>
          <Codemirror
            v-if="tabName === key"
            v-model:value="item.code"
            height="600px"
            :options="cmOptions[item.option]"
            class="dk-code-mirror"
          />
        </el-tab-pane>

        <div style="text-align: center; padding: 10px">
          <el-button type="primary" @click="zipGenerate()">下载代码</el-button>
          <el-button type="danger" @click="updateSql()">执行数据表更新</el-button>
          <el-button type="primary" @click="save()">保存配置</el-button>
          <el-button type="warning" :loading="overwriteAllLoading" @click="overwriteAllFiles"> 覆盖全部文件 </el-button>
        </div>
      </el-tabs>
    </el-dialog>
    <el-dialog v-model="dialogCrudVisible" width="1200px" title="数据表列表">
      <crud-list v-if="addon.id && dialogCrudVisible" :aid="addon.id" />
    </el-dialog>

    <!-- AI 设计弹窗 -->
    <el-dialog v-model="showAiDialog" title="AI 智能设计" width="600px" :close-on-click-modal="false" :close-on-press-escape="false">
      <div v-if="!aiLoading" class="ai-design-form">
        <el-form label-width="80px">
          <el-form-item label="设计需求">
            <el-input
              v-model="aiPrompt"
              type="textarea"
              :rows="6"
              placeholder="请详细描述您的需求，例如：&#10;1. 创建一个用户管理表&#10;2. 添加用户身份字段，需要有管理员、会员、代理&#10;3. 完善当前表结构，添加常用字段"
              maxlength="500"
              show-word-limit
            />
          </el-form-item>
        </el-form>
      </div>

      <!-- AI 处理中的加载界面 -->
      <div v-else class="ai-loading-container">
        <div class="loading-content">
          <img :src="loadingGif" alt="AI处理中..." class="loading-gif" />
          <p class="loading-text">AI 正在智能设计中，请勿退出，请稍候...</p>
          <p class="loading-tip">{{ loadingTips[currentTipIndex] }}</p>
        </div>

        <!-- 流式数据展示区域 -->
        <div v-if="streamData" class="stream-data-container">
          <div class="stream-header">
            <span class="stream-title">AI 生成过程</span>
            <div class="stream-actions">
              <el-button type="text" @click="showStreamDetail = !showStreamDetail">
                {{ showStreamDetail ? '收起' : '展开' }}
              </el-button>
            </div>
          </div>
          <div v-show="showStreamDetail" class="stream-content">
            <div class="stream-output">
              <Codemirror v-model:value="streamData" height="300px" :options="streamCmOptions" class="stream-codemirror" :readonly="true" />
            </div>
          </div>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button v-if="!aiLoading" @click="showAiDialog = false">取消</el-button>
          <el-button v-if="!aiLoading" type="primary" :disabled="!aiPrompt.trim()" @click="handleAiDesign"> 开始 AI 设计 </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 历史记录弹窗 -->
    <el-dialog v-model="showHistoryDialog" title="历史记录" width="1200px" :close-on-click-modal="false">
      <div v-loading="historyLoading" class="history-dialog-content">
        <el-table v-if="historyList.length > 0" :data="historyList" stripe style="width: 100%">
          <el-table-column prop="id" label="ID" width="60" />
          <el-table-column label="表名" width="150">
            <template #default="{ row }">
              {{ row.design_data?.table?.name || '未命名表' }}
            </template>
          </el-table-column>
          <!-- <el-table-column label="表注释" width="150">
            <template #default="{ row }">
              {{ row.design_data?.table?.comment || '无注释' }}
            </template>
          </el-table-column> -->
          <el-table-column label="字段数量">
            <template #default="{ row }">
              {{ row.design_data?.fieldItems?.length || 0 }}
            </template>
          </el-table-column>
          <el-table-column label="备注">
            <template #default="{ row }">
              <span v-if="!row.editingRemark">{{ row.remark || '-' }}</span>
              <el-input v-else v-model="row.tempRemark" @blur="saveRemark(row)" @keyup.enter="saveRemark(row)" />
            </template>
          </el-table-column>
          <el-table-column label="创建时间">
            <template #default="{ row }">
              {{ row.create_time }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="220" fixed="right">
            <template #default="{ row, $index }">
              <div class="flex gap-1">
                <el-button type="primary" size="small" @click="applyHistory(row)">应用</el-button>
                <el-button type="info" size="small" @click="viewHistoryData(row)">查看数据</el-button>
                <el-popconfirm title="确定删除这条历史记录吗？" @confirm="deleteHistory(row, $index)">
                  <template #reference>
                    <el-button type="danger" size="small">删除</el-button>
                  </template>
                </el-popconfirm>
              </div>
            </template>
          </el-table-column>
        </el-table>
        <div v-else-if="!historyLoading" class="text-center py-8">
          <el-empty description="暂无历史记录" />
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="showHistoryDialog = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 查看历史数据弹窗 -->
    <el-dialog v-model="showHistoryDataDialog" title="历史数据详情" width="1000px" :close-on-click-modal="false">
      <div v-if="currentHistoryData" class="history-data-content">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="记录ID">{{ currentHistoryData.id }}</el-descriptions-item>
          <el-descriptions-item label="CRUD ID">{{ currentHistoryData.crud_id }}</el-descriptions-item>
          <el-descriptions-item label="表名">{{ currentHistoryData.parsedDesignData?.table?.name || '-' }}</el-descriptions-item>
          <el-descriptions-item label="表注释">{{ currentHistoryData.parsedDesignData?.table?.comment || '-' }}</el-descriptions-item>
          <el-descriptions-item label="字段数量">{{ currentHistoryData.parsedDesignData?.fieldItems?.length || 0 }}</el-descriptions-item>
          <el-descriptions-item label="备注">{{ currentHistoryData.remark || '-' }}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{ currentHistoryData.create_time }}</el-descriptions-item>
          <el-descriptions-item label="更新时间">{{ currentHistoryData.update_time }}</el-descriptions-item>
        </el-descriptions>

        <el-divider content-position="left">字段信息</el-divider>
        <el-table v-if="currentHistoryData.parsedDesignData?.fieldItems" :data="currentHistoryData.parsedDesignData.fieldItems" stripe>
          <el-table-column prop="name" label="字段名" width="120" />
          <el-table-column prop="comment" label="字段注释" />
          <el-table-column prop="type" label="类型" />
          <el-table-column prop="length" label="长度" width="60" />
          <el-table-column label="主键" width="60" align="center">
            <template #default="{ row }">
              <el-tag v-if="row.primaryKey" type="danger">是</el-tag>
              <span v-else>-</span>
            </template>
          </el-table-column>
          <el-table-column label="自增" width="60" align="center">
            <template #default="{ row }">
              <el-tag v-if="row.autoIncrement" type="success">是</el-tag>
              <span v-else>-</span>
            </template>
          </el-table-column>
          <el-table-column label="允许空" width="70" align="center">
            <template #default="{ row }">
              <el-tag v-if="row.null" type="info">是</el-tag>
              <span v-else>-</span>
            </template>
          </el-table-column>
          <el-table-column prop="default" label="默认值" width="100" />
          <el-table-column prop="designType" label="设计类型" width="100" />
        </el-table>

        <div class="json-data-container border border-gray-200 rounded-lg overflow-hidden">
          <div class="json-header flex justify-between items-center p-3 bg-gray-50 border-b border-gray-200">
            <span class="text-sm font-medium text-gray-700">完整设计数据 (JSON)</span>
            <el-button type="text" @click="showJsonDetail = !showJsonDetail">
              {{ showJsonDetail ? '收起' : '展开' }}
            </el-button>
          </div>
          <div v-show="showJsonDetail" class="json-content">
            <Codemirror
              v-model:value="currentHistoryDataJson"
              height="300px"
              :options="historyDataCmOptions"
              class="history-data-codemirror"
              :readonly="true"
            />
          </div>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="applyHistory(currentHistoryData)">应用此版本</el-button>
          <el-button @click="showHistoryDataDialog = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script>
// @ts-nocheck
import { getAddonById } from '@/api/addons/addon'
import draggable from 'vuedraggable'
import { commonFields } from '@/views/crud/crud/crud'
import _ from 'lodash'
import CrudForm from '@/views/crud/components/CrudForm.vue'
import { generate, getById, saveDesign, updateSql, overwriteFile } from '@/api/crud'
import { crud as aiCrud } from '@/api/agent'
import { getList as getCrudHistoryList, del as deleteCrudHistory } from '@/api/crud_history'
import TableForm from '@/views/crud/components/TableForm.vue'
// @ts-ignore
import { defineAsyncComponent } from 'vue'
import CrudList from '@/views/crud/components/crudList.vue'
import loadingGif from '@/assets/default/loading.gif'
import { getPlaid, getToken } from '@/utils/auth'
import { DArrowLeft, DArrowRight } from '@element-plus/icons-vue'

const commonOptions = {
  tabSize: 12,
  theme: 'monokai',
  lineNumbers: true
}
export default {
  components: {
    CrudList,
    TableForm,
    CrudForm,
    draggable,
    DArrowLeft,
    DArrowRight
  },
  data() {
    return {
      row: {},
      loading: false,
      tabName: 'page',
      sloading: true,
      dialogCodeVisible: false,
      dialogCrudVisible: false,
      commonFields: [],
      fieldItems: [],
      table: {
        name: '',
        comment: ''
      },
      chooseFieldKey: 0,
      activeName: 'mysql',
      defaultTypeOptions: [
        { label: '手动输入', value: 'INPUT' },
        { label: 'EMPTY STRING（空字符串）', value: 'EMPTY STRING' },
        { label: 'NULL', value: 'NULL' },
        { label: '无（不设置默认值）', value: 'NONE' }
      ],
      addon: {},
      dialogVisible: false,
      codes: {},
      // 覆盖文件相关状态
      overwriteLoading: false,
      overwriteAllLoading: false,
      // AI 设计相关
      showAiDialog: false,
      aiLoading: false,
      aiPrompt: '',
      loadingGif,
      // 历史记录相关
      showHistoryDialog: false,
      historyList: [],
      historyLoading: false,
      // 查看历史数据弹窗
      showHistoryDataDialog: false,
      currentHistoryData: null,
      showJsonDetail: false, // 控制JSON数据的展开/收起
      // 可调整布局相关
      layoutConfig: {
        leftWidth: 280, // 左侧面板宽度
        rightWidth: 300, // 右侧面板宽度
        leftCollapsed: false, // 左侧面板是否折叠
        rightCollapsed: false // 右侧面板是否折叠
      },
      isDragging: false,
      dragType: '', // 'left' 或 'right'
      startX: 0,
      startWidth: 0,
      currentTipIndex: 0,
      tipInterval: null,
      streamData: '', // 流式数据
      showStreamDetail: true, // 是否显示流式数据详情
      loadingTips: [
        '正在分析您的需求...',
        '智能匹配最佳字段类型...',
        '优化表结构设计...',
        '生成字段配置...',
        '验证数据完整性...',
        '即将完成设计...'
      ],
      cmOptions: {
        php: {
          ...commonOptions,
          mode: 'text/x-php'
        },
        vue: {
          ...commonOptions,
          mode: 'text/x-vue'
        },
        javascript: {
          ...commonOptions,
          mode: 'text/javascript'
        },
        sql: {
          ...commonOptions,
          mode: 'text/x-sql'
        }
      },
      // 流式数据展示的CodeMirror配置
      streamCmOptions: {
        tabSize: 2,
        theme: 'monokai',
        lineNumbers: true,
        mode: 'application/json',
        readOnly: true,
        lineWrapping: true,
        foldGutter: true,
        gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
        autoCloseBrackets: true,
        matchBrackets: true,
        showCursorWhenSelecting: true,
        styleActiveLine: false
      },
      // 历史数据展示的CodeMirror配置
      historyDataCmOptions: {
        tabSize: 2,
        theme: 'monokai',
        lineNumbers: true,
        mode: 'application/json',
        readOnly: true,
        lineWrapping: true,
        foldGutter: true,
        gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
        autoCloseBrackets: true,
        matchBrackets: true,
        showCursorWhenSelecting: true,
        styleActiveLine: false
      }
    }
  },
  computed: {
    designData() {
      return {
        aid: this.addon.id,
        fieldItems: this.fieldItems,
        table: this.table
      }
    },
    currentHistoryDataJson() {
      return this.currentHistoryData ? JSON.stringify(this.currentHistoryData.parsedDesignData, null, 2) : ''
    }
  },
  mounted() {
    // 监听全局 keydown 事件
    window.addEventListener('keydown', this.handleKeyDown)
    console.log('this.$route', this.$route)
    // 初始化commonFields的深拷贝，确保拖拽源数据不被污染
    this.initCommonFields()
    this.getAddonById()
    this.getById(this.$route.query?.id)
    // 加载布局配置
    this.loadLayoutConfig()
  },
  beforeUnmount() {
    // 移除事件监听器，防止内存泄漏
    window.removeEventListener('keydown', this.handleKeyDown)
    // 清理定时器
    this.stopLoadingTips()
  },
  methods: {
    // 初始化commonFields，创建深拷贝确保数据源不被污染
    initCommonFields() {
      // 从外部导入的commonFields创建深拷贝
      this.commonFields = _.cloneDeep(commonFields)
    },
    // 拖拽时克隆字段，确保每次拖拽都是全新的独立对象
    cloneField(original) {
      const clone = _.cloneDeep(original)
      // 生成新的唯一ID
      clone._id = this.genId()

      // 确保有默认的name和comment
      // 如果原始数据有name就保留，没有就用title生成
      if (!clone.name && clone.title) {
        clone.name = clone.title.toLowerCase().replace(/[^a-z0-9]/g, '_')
      }
      // 如果原始数据有comment就保留，没有就用title
      if (!clone.comment && clone.title) {
        clone.comment = clone.title
      }

      return clone
    },
    genId() {
      // 生成更加唯一的ID，包含时间戳和随机数
      const timestamp = Date.now().toString(36)
      const random = Math.random().toString(36).slice(2, 11)
      return `f_${timestamp}_${random}`
    },
    handleKeyDown(event) {
      // 检查是否按下的是 Ctrl + S
      if ((event.ctrlKey || event.metaKey) && event.key === 's') {
        event.preventDefault() // 防止浏览器默认行为（如保存页面）
        this.save()
      }
    },
    getById(id) {
      if (id) {
        this.loading = true
        getById(id).then((res) => {
          console.log(res)
          if (res.data.design_data) {
            this.fieldItems = (res.data.design_data.fieldItems || []).map((it) => ({
              _id: it._id || this.genId(),
              ...it
            }))
            this.table = res.data.design_data.table
            this.row = res.data
          }
          this.loading = false
        })
      }
    },
    save() {
      // 检查一下是否有表名和表注释
      if (!this.table.name || !this.table.comment) {
        this.$message.warning('请输入表名和表注释')
        return
      }
      // 判断表设计里面是否有字段
      if (this.fieldItems.length === 0) {
        this.$message.warning('请添加字段')
        return
      }
      // 判断是否添加了主键
      let hasPrimaryKey = false
      this.fieldItems.forEach((item) => {
        if (item.primaryKey) {
          hasPrimaryKey = true
        }
      })
      if (!hasPrimaryKey) {
        this.$message.warning('请添加主键')
        return
      }
      // 判断是否有重复的字段名
      const fieldNames = []
      this.fieldItems.forEach((item) => {
        if (fieldNames.includes(item.name)) {
          this.$message.warning('字段名重复')
          return
        }
        fieldNames.push(item.name)
      })
      saveDesign(this.designData, this.row.id).then((res) => {
        this.$message.success(res.msg)
        this.row = res.data
        if (res.other.op === 'add') {
          this.$router.push('/crud/' + res.data.aid + '?id=' + res.data.id)
        }
      })
    },
    updateSql() {
      updateSql(this.designData).then((res) => {
        if (res.data.type) {
          this.$message.warning(res.msg)
        } else {
          this.$message.success(res.msg)
        }
      })
    },
    onChange(evt) {
      if (evt.added) {
        // 由于使用了clone函数，evt.added.element已经是独立的对象
        const element = evt.added.element

        // 处理特殊类型映射
        if (['enum', 'set'].includes(element.type)) {
          element.type = element.dataType
        }

        // Vue 3中直接赋值即可，无需使用$set
        this.fieldItems[evt.added.newIndex] = element
      }
    },
    copyItem(key) {
      // 深拷贝字段项，避免引用共享导致修改内容同时变化
      const originalItem = this.fieldItems[key]
      const copiedItem = {
        ...originalItem,
        _id: this.genId(), // 为复制的项生成新的ID
        // 深拷贝嵌套对象
        table: { ...originalItem.table },
        form: { ...originalItem.form }
      }
      this.fieldItems.splice(key, 0, copiedItem)
    },
    deleteItem(key) {
      this.fieldItems.splice(key, 1)
    },
    getAddonById() {
      getAddonById(this.$route.params.aid).then((res) => {
        console.log(res)
        this.addon = res.data
        this.$parent.title = 'CRUD代码生成-' + this.addon.title
      })
    },
    zipGenerate() {
      generate(this.designData, 1).then((res) => {
        window.open(res.data.url)
      })
    },
    generate() {
      generate(this.designData)
        .then((res) => {
          console.log(res)
          this.codes = res.data
          // this.codes.create_sql.code = '\n' + this.codes.create_sql.code
          this.sloading = false
          this.dialogCodeVisible = true
        })
        .catch((err) => {
          this.$message.error(err.msg)
        })
    },

    // AI 设计相关方法
    async handleAiDesign() {
      if (!this.aiPrompt.trim()) {
        this.$message.warning('请输入设计需求')
        return
      }

      this.aiLoading = true
      this.streamData = ''
      this.startLoadingTips()

      try {
        // 调用流式 AI 接口
        const crudId = this.row.id || 0
        await this.streamAiRequest(this.aiPrompt, crudId)
      } catch (error) {
        console.error('AI 设计出错:', error)
        this.$message.error('AI 设计出错: ' + error.message)
      } finally {
        this.aiLoading = false
        this.stopLoadingTips()
      }
    },

    // 流式请求处理
    async streamAiRequest(prompt, crudId) {
      const path = '/' + import.meta.env.VITE_BASE_ADDON_NAME + '/agent/'
      console.log('this.$store', this.$store)
      try {
        const response = await fetch(import.meta.env.VITE_BASE_URL + path + 'crud', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Access-Token': getToken()
          },
          body: JSON.stringify({
            prompt,
            crud_id: crudId
          })
        })

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`)
        }

        const reader = response.body.getReader()
        const decoder = new TextDecoder()
        let buffer = ''

        while (true) {
          const { done, value } = await reader.read()
          if (done) {
            console.log('this.streamData', this.streamData)
            this.applyAiResult(JSON.parse(this.streamData))
            this.$message.success('AI 设计完成！')
            this.showAiDialog = false
            this.aiPrompt = ''
            this.streamData = ''
            break
          }
          const chunk = decoder.decode(value, { stream: true })
          buffer += chunk
          this.streamData = buffer
        }
      } catch (error) {
        console.error('流式请求出错:', error)
        throw error
      }
    },

    // 应用 AI 设计结果
    applyAiResult(data) {
      try {
        // 应用表信息
        if (data.table) {
          this.table = { ...this.table, ...data.table }
        }

        // 应用字段信息
        if (data.fieldItems && Array.isArray(data.fieldItems)) {
          const newFields = data.fieldItems.map((field) => ({
            ...field,
            _id: field._id || this.genId()
          }))

          this.fieldItems = newFields
          this.chooseFieldKey = 0 // 选中第一个字段
        }
      } catch (error) {
        console.error('应用 AI 结果出错:', error)
        this.$message.error('应用 AI 设计结果出错')
      }
    },

    // 开始加载提示轮播
    startLoadingTips() {
      this.currentTipIndex = 0
      this.tipInterval = setInterval(() => {
        this.currentTipIndex = (this.currentTipIndex + 1) % this.loadingTips.length
      }, 2000)
    },

    // 停止加载提示轮播
    stopLoadingTips() {
      if (this.tipInterval) {
        clearInterval(this.tipInterval)
        this.tipInterval = null
      }
    },

    // 显示历史记录弹窗
    openHistoryDialog() {
      this.showHistoryDialog = true
      this.getHistoryList()
    },

    // 获取历史记录列表
    async getHistoryList() {
      if (!this.row.id) {
        this.$message.warning('请先保存当前设计')
        return
      }

      this.historyLoading = true
      try {
        const searchData = {
          crud_id: this.row.id
        }
        const response = await getCrudHistoryList(1, 10, searchData)
        console.log('历史记录响应:', response)
        this.historyList = response.data || []
      } catch (error) {
        console.error('获取历史记录失败:', error)
        this.$message.error('获取历史记录失败')
      } finally {
        this.historyLoading = false
      }
    },

    // 应用历史记录
    applyHistory(historyItem) {
      try {
        if (historyItem.design_data) {
          let designData = historyItem.design_data

          // 如果design_data是字符串，需要解析
          if (typeof designData === 'string') {
            designData = JSON.parse(designData)
          }

          // 应用表信息
          if (designData.table) {
            this.table = { ...this.table, ...designData.table }
          }

          // 应用字段信息
          if (designData.fieldItems && Array.isArray(designData.fieldItems)) {
            this.fieldItems = designData.fieldItems.map((field) => ({
              ...field,
              _id: field._id || this.genId()
            }))
            this.chooseFieldKey = 0
          }

          this.showHistoryDialog = false
          this.$message.success(`已应用历史记录：${designData.table?.name || '未命名表'}`)
        } else {
          this.$message.warning('该历史记录没有设计数据')
        }
      } catch (error) {
        console.error('应用历史记录失败:', error)
        this.$message.error('应用历史记录失败: ' + error.message)
      }
    },

    // 查看历史数据
    viewHistoryData(historyItem) {
      try {
        let designData = historyItem.design_data
        if (typeof designData === 'string') {
          designData = JSON.parse(designData)
        }
        this.currentHistoryData = {
          ...historyItem,
          parsedDesignData: designData
        }
        this.showJsonDetail = false // 默认收起JSON数据
        this.showHistoryDataDialog = true
      } catch (error) {
        console.error('解析历史数据失败:', error)
        this.$message.error('解析历史数据失败')
      }
    },

    // 编辑备注
    editRemark(row) {
      row.editingRemark = true
      row.tempRemark = row.remark || ''
    },

    // 保存备注
    async saveRemark(row) {
      try {
        // 这里应该调用更新备注的API，但crud_history.js中没有更新接口
        // 暂时只更新本地数据
        row.remark = row.tempRemark
        row.editingRemark = false
        this.$message.success('备注已更新')
        // TODO: 调用后端API更新备注
      } catch (error) {
        console.error('保存备注失败:', error)
        this.$message.error('保存备注失败')
      }
    },

    // 删除历史记录
    async deleteHistory(row, index) {
      try {
        await deleteCrudHistory(row.id)
        this.historyList.splice(index, 1)
        this.$message.success('历史记录已删除')
      } catch (error) {
        console.error('删除历史记录失败:', error)
        this.$message.error('删除历史记录失败')
      }
    },

    // 可调整布局相关方法
    // 开始拖拽调整大小
    startResize(type, event) {
      this.isDragging = true
      this.dragType = type
      this.startX = event.clientX
      this.startWidth = type === 'left' ? this.layoutConfig.leftWidth : this.layoutConfig.rightWidth

      document.addEventListener('mousemove', this.handleResize)
      document.addEventListener('mouseup', this.stopResize)
      document.body.style.cursor = 'col-resize'
      document.body.style.userSelect = 'none'
    },

    // 处理拖拽调整
    handleResize(event) {
      if (!this.isDragging) return

      const deltaX = event.clientX - this.startX
      let newWidth

      if (this.dragType === 'left') {
        newWidth = Math.max(200, Math.min(600, this.startWidth + deltaX))
        this.layoutConfig.leftWidth = newWidth
      } else if (this.dragType === 'right') {
        newWidth = Math.max(200, Math.min(600, this.startWidth - deltaX))
        this.layoutConfig.rightWidth = newWidth
      }

      // 保存到本地存储
      this.saveLayoutConfig()
    },

    // 停止拖拽
    stopResize() {
      this.isDragging = false
      this.dragType = ''
      document.removeEventListener('mousemove', this.handleResize)
      document.removeEventListener('mouseup', this.stopResize)
      document.body.style.cursor = ''
      document.body.style.userSelect = ''
    },

    // 切换左侧面板
    toggleLeftPanel() {
      this.layoutConfig.leftCollapsed = !this.layoutConfig.leftCollapsed
      this.saveLayoutConfig()
    },

    // 切换右侧面板
    toggleRightPanel() {
      this.layoutConfig.rightCollapsed = !this.layoutConfig.rightCollapsed
      this.saveLayoutConfig()
    },

    // 保存布局配置到本地存储
    saveLayoutConfig() {
      localStorage.setItem('crud-layout-config', JSON.stringify(this.layoutConfig))
    },

    // 从本地存储加载布局配置
    loadLayoutConfig() {
      const saved = localStorage.getItem('crud-layout-config')
      if (saved) {
        try {
          const config = JSON.parse(saved)
          this.layoutConfig = { ...this.layoutConfig, ...config }
        } catch (error) {
          console.error('加载布局配置失败:', error)
        }
      }
    },

    // 覆盖当前文件
    async overwriteCurrentFile(fileKey, fileItem) {
      if (!fileItem.path || fileItem.path === '无') {
        this.$message.warning('该文件无法覆盖')
        return
      }

      // 确认对话框
      try {
        await this.$confirm(
          `确定要覆盖文件 "${fileItem.label}" 吗？\n路径: ${fileItem.path}\n\n此操作将直接修改服务器文件，无法撤销！`,
          '确认覆盖文件',
          {
            confirmButtonText: '确定覆盖',
            cancelButtonText: '取消',
            type: 'warning',
            dangerouslyUseHTMLString: false
          }
        )
      } catch {
        return // 用户取消
      }

      try {
        this.overwriteLoading = true

        const fileData = {
          [fileKey]: {
            path: fileItem.path,
            code: fileItem.code,
            label: fileItem.label
          }
        }

        const response = await overwriteFile(fileData, this.addon.name)

        if (response.code === 1) {
          this.$message.success(`文件 ${fileItem.label} 覆盖成功`)
        } else {
          this.$message.error(response.msg || '文件覆盖失败')
        }
      } catch (error) {
        console.error('覆盖文件失败:', error)
        this.$message.error('覆盖文件失败: ' + (error.message || '未知错误'))
      } finally {
        this.overwriteLoading = false
      }
    },

    // 覆盖全部文件
    async overwriteAllFiles() {
      if (!this.codes || Object.keys(this.codes).length === 0) {
        this.$message.warning('没有可覆盖的文件')
        return
      }

      // 过滤掉无效的文件
      const validFiles = Object.entries(this.codes).filter(([key, item]) => item.path && item.path !== '无' && item.code)

      if (validFiles.length === 0) {
        this.$message.warning('没有有效的文件可以覆盖')
        return
      }

      // 确认对话框
      try {
        await this.$confirm(
          `确定要覆盖全部 ${validFiles.length} 个文件吗？\n\n此操作将直接修改服务器文件，无法撤销！\n\n将要覆盖的文件：\n${validFiles
            .map(([key, item]) => `• ${item.label} (${item.path})`)
            .join('\n')}`,
          '确认覆盖全部文件',
          {
            confirmButtonText: '确定覆盖全部',
            cancelButtonText: '取消',
            type: 'warning',
            dangerouslyUseHTMLString: false
          }
        )
      } catch {
        return // 用户取消
      }

      try {
        this.overwriteAllLoading = true

        // 构建文件数据
        const fileData = {}
        validFiles.forEach(([key, item]) => {
          fileData[key] = {
            path: item.path,
            code: item.code,
            label: item.label
          }
        })

        const response = await overwriteFile(fileData, this.addon.name)

        if (response.code === 1) {
          const { summary } = response.data
          this.$message.success(`文件覆盖完成！成功: ${summary.success}个，失败: ${summary.error}个`)

          // 显示详细结果
          if (summary.error > 0) {
            console.warn('部分文件覆盖失败，详细信息:', response.data.results)
          }
        } else {
          this.$message.error(response.msg || '文件覆盖失败')
        }
      } catch (error) {
        console.error('覆盖全部文件失败:', error)
        this.$message.error('覆盖全部文件失败: ' + (error.message || '未知错误'))
      } finally {
        this.overwriteAllLoading = false
      }
    }
  }
}
</script>

<style scoped lang="scss">
.dk-code-mirror {
  font-size: 14px;
  &::v-deep {
    .CodeMirror {
      height: calc(100vh - 400px);
    }
  }
}

.crud-content {
  h4 {
    padding: 10px 0;
    font-size: 14px;
    font-weight: 500;
  }

  .crud-body {
    padding-top: 10px;

    .col-content {
      border-radius: 5px;
      background: #fff;
      padding: 15px;
      height: calc(100vh - 180px);
    }
  }
}

// 可调整布局样式
.resizable-layout {
  display: flex;
  gap: 0;
  height: calc(100vh - 180px);
  position: relative;

  .layout-panel {
    background: #fff;
    border-radius: 5px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

    &.left-panel {
      flex-shrink: 0;
    }

    &.center-panel {
      flex: 1;
      margin: 0 8px;
      min-width: 400px;
    }

    &.right-panel {
      flex-shrink: 0;
    }

    .panel-header {
      padding: 12px 16px;
      background: #f8f9fa;
      border-bottom: 1px solid #e9ecef;
      display: flex;
      justify-content: space-between;
      align-items: center;
      min-height: 48px;

      h4 {
        margin: 0;
        font-size: 14px;
        font-weight: 500;
        color: #333;
      }

      .panel-controls {
        display: flex;
        gap: 4px;
      }
    }

    .panel-content {
      flex: 1;
      padding: 15px;
      overflow: auto;

      &.field-content {
        .drag-field {
          overflow: auto;
        }

        position: relative;

        .field-item-list {
          &::v-deep {
            .el-form-item {
              margin-bottom: 0;
            }
          }

          width: 100%;
          background: #fff;
          margin: 10px 0;
          border-radius: 5px;
          padding: 10px;
          cursor: move;
          display: flex;
          justify-content: space-between;
          border: 1px solid #fff;

          &.choose {
            background: #ecf5ff;
            border: 1px solid #d9ecff;
          }
        }

        .no-fieldItems {
          position: absolute;
          top: 150px;
          left: 0;
          right: 0;
        }
      }
    }
  }

  .resize-handle {
    width: 4px;
    background: transparent;
    cursor: col-resize;
    position: relative;
    flex-shrink: 0;
    z-index: 10;

    &:hover {
      background: #409eff;
    }

    &:before {
      content: '';
      position: absolute;
      top: 0;
      left: -2px;
      right: -2px;
      bottom: 0;
      background: transparent;
    }

    &.left-handle {
      margin-right: 4px;
    }

    &.right-handle {
      margin-left: 4px;
    }
  }

  .collapsed-trigger {
    width: 32px;
    background: #f8f9fa;
    border: 1px solid #e9ecef;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.3s ease;
    writing-mode: vertical-lr;
    text-orientation: mixed;
    flex-shrink: 0;

    &:hover {
      background: #e9ecef;
      border-color: #409eff;
    }

    &.left-trigger {
      margin-right: 8px;
    }

    &.right-trigger {
      margin-left: 8px;
    }

    .el-icon {
      font-size: 16px;
      color: #666;
      margin-bottom: 8px;
    }

    .trigger-text {
      font-size: 12px;
      color: #666;
      white-space: nowrap;
    }
  }
}

// AI 设计弹窗样式
.ai-design-form {
  padding: 20px 0;
}

.ai-loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 300px;

  .loading-content {
    text-align: center;
    margin-bottom: 20px;

    .loading-gif {
      width: 150px;
      margin-bottom: 20px;
    }

    .loading-text {
      font-size: 16px;
      font-weight: 500;
      color: #409eff;
      margin: 0 0 10px 0;
    }

    .loading-tip {
      font-size: 14px;
      color: #909399;
      margin: 0;
      min-height: 20px;
      transition: opacity 0.3s ease;
    }
  }

  .stream-data-container {
    width: 100%;
    border: 1px solid #e4e7ed;
    border-radius: 6px;
    overflow: hidden;

    .stream-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 10px 15px;
      background-color: #f5f7fa;
      border-bottom: 1px solid #e4e7ed;

      .stream-title {
        font-size: 14px;
        font-weight: 500;
        color: #303133;
      }

      .stream-actions {
        display: flex;
        gap: 8px;
      }
    }

    .stream-content {
      .stream-output {
        background-color: #fafafa;
        .stream-codemirror {
          font-size: 12px;
          border: 1px solid #e4e7ed;
          border-radius: 4px;
          overflow: hidden;

          :deep(.CodeMirror) {
            height: 300px !important;
            font-size: 12px;
            line-height: 1.4;

            .CodeMirror-scroll {
              max-height: 300px;
            }

            .CodeMirror-gutters {
              border-right: 1px solid #e4e7ed;
              background-color: #f8f9fa;
            }

            .CodeMirror-linenumber {
              color: #909399;
              font-size: 11px;
            }
          }
        }
      }
    }
  }
}

// 历史数据查看弹窗样式
.history-data-content {
  .json-data-container {
    margin-top: 16px;

    .json-header {
      user-select: none;
      transition: background-color 0.2s ease;

      &:hover {
        background-color: #f0f2f5;
      }
    }

    .json-content {
      .history-data-codemirror {
        border: none;
        border-radius: 0;
        overflow: hidden;

        :deep(.CodeMirror) {
          height: 300px !important;
          font-size: 12px;
          line-height: 1.4;
          border: none;

          .CodeMirror-scroll {
            max-height: 300px;
          }

          .CodeMirror-gutters {
            border-right: 1px solid #e4e7ed;
            background-color: #f8f9fa;
          }

          .CodeMirror-linenumber {
            color: #909399;
            font-size: 11px;
          }
        }
      }
    }
  }
}
</style>
